package cn.itcast.account.service;

import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;

/**
 * 声明TCC接口 实现余额 扣减（冻结） 删除冻结记录 恢复冻结金额
 * 1.接口上使用@LocalTCC注解
 * 2.修改每个接口的方法名、参数、返回结果类型
 * 三个方法的名称 必须跟@TwoPhaseBusinessAction中的 name commitMethod rollbackMethod名称一致
 */
@LocalTCC
public interface TCCService {

    /**
     * 一阶段Try逻辑，@TwoPhaseBusinessAction中的name属性要与当前方法名一致，用于指定Try逻辑对应的方法
     * BusinessActionContextParameter 接收参数
     * name属性要与当前方法名一致，用于指定Try逻辑对应的方法
     * commitMethod属性要跟提交方法名一致，用于业务执行和提交
     * rollbackMethod属性要跟提交方法名一致，预留资源的释放
     * @param userId
     * @param money
     * @return
     */
    @TwoPhaseBusinessAction(name = "deduct", commitMethod = "comfirm", rollbackMethod = "cancel")
    boolean deduct(@BusinessActionContextParameter(paramName = "userId") String userId,
                   @BusinessActionContextParameter(paramName = "money") int money);

    /**
     * 二阶段confirm确认方法、可以另命名，但要保证与commitMethod一致
     * @param actionContext tcc接口上下文对象,可以传递try方法的参数,还可以获取事务id
     * @return 执行是否成功
     */
    boolean comfirm(BusinessActionContext actionContext);

    /**
     * 二阶段回滚方法，要保证与rollbackMethod一致
     * @param actionContext
     * @return
     */
    boolean cancel(BusinessActionContext actionContext);
}